package com.cloudinnov.logic.impl;

import java.io.IOException;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cloudinnov.dao.EquipmentPointsDao;
import com.cloudinnov.dao.EquipmentsAttrDao;
import com.cloudinnov.dao.EquipmentsDao;
import com.cloudinnov.logic.EquipmentPointLogic;
import com.cloudinnov.model.EquipmentPoints;
import com.cloudinnov.model.Equipments;
import com.cloudinnov.model.EquipmentsAttr;
import com.cloudinnov.model.PointExport;
import com.cloudinnov.utils.CodeUtil;
import com.cloudinnov.utils.CommonUtils;
import com.cloudinnov.utils.JudgeNullUtil;
import com.cloudinnov.utils.POIUtils;
import com.cloudinnov.utils.TcpClientUtil;
import com.cloudinnov.utils.model.BxClientModel;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

/**
 * @author guochao
 * @date 2016年2月17日下午5:24:56
 * @email chaoguo@cloudinnov.com
 * @remark 设备点位service实现
 * @version
 */
@Service("equipmentPointsLogic")
public class EquipmentPointsLogicImpl extends BaseLogicImpl<EquipmentPoints> implements EquipmentPointLogic {
	private static final Logger LOG = LoggerFactory.getLogger(EquipmentPointsLogicImpl.class);
	@Autowired
	private EquipmentPointsDao equipmentPointsDao;
	@Autowired
	private EquipmentsDao equipmentDao;
	@Autowired
	private EquipmentsAttrDao equipmentsAttrDao;

	public int save(EquipmentPoints equipmentPoints) {
		String equipmentCode = equipmentPoints.getEquipmentCode();
		if (equipmentPoints.getCustomerCode() == null || equipmentPoints.getCustomerCode() == "") {
			String customerCode = equipmentDao.selectCustomerCodeByEquipmentCode(equipmentCode);
			equipmentPoints.setCustomerCode(customerCode);
		}
		String code = CodeUtil.pointCode(7, equipmentPoints.getType(), equipmentPoints.getKind());
		if (code == "") {
			return 0;
		}
		equipmentPoints.setCode(code);
		equipmentPoints.setStatus(CommonUtils.STATUS_NORMAL);
		if (equipmentPoints.getEquipmentCode().substring(0, 2).equals("PL")) {
			equipmentPoints.setRange(CommonUtils.RANGE_LINE_TYPE);
		} else if (equipmentPoints.getEquipmentCode().substring(0, 2).equals("EQ")) {
			equipmentPoints.setRange(CommonUtils.RANGE_EQU_TYPE);
		}
		int result = equipmentPointsDao.insert(equipmentPoints);
		if (result == 1) {
			return equipmentPointsDao.insertInfo(equipmentPoints);
		} else {
			return 0;
		}
	}
	@Override
	public int update(EquipmentPoints equipmentPoints) {
		int returnCode = equipmentPointsDao.updateByCondition(equipmentPoints);
		returnCode = equipmentPointsDao.updateInfoByCondition(equipmentPoints);
		return returnCode;
	}
	@Override
	public List<EquipmentPoints> selectSimulationAllPoint() {
		return equipmentPointsDao.selectSimulationAllPoint();
	}
	@Override
	public List<EquipmentPoints> listByCode(String[] codes, String language) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("language", language);
		map.put("codes", codes);
		return equipmentPointsDao.listByCode(map);
	}
	@Override
	public int saveOtherLanguage(EquipmentPoints equipmentPoints) {
		return equipmentPointsDao.insertInfo(equipmentPoints);
	}
	@Override
	public Page<EquipmentPoints> selectProductionLineListPage(int index, int size, EquipmentPoints equipmentPoint,
			boolean isOrderBy) {
		PageHelper.startPage(index, size);
		if (isOrderBy) {
			PageHelper.orderBy("create_time desc");
		}
		return (Page<EquipmentPoints>) equipmentPointsDao.selectProductionLineListPage(equipmentPoint);
	}
	@Override
	public int updateOtherLanguage(EquipmentPoints equipmentPoints) {
		return equipmentPointsDao.updateInfoByCondition(equipmentPoints);
	}
	@Override
	public List<EquipmentPoints> monitorEqusPoints(String[] codes, String language) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("codes", codes);
		map.put("language", language);
		return equipmentPointsDao.monitorEqusPoints(map);
	}
	@Override
	public List<EquipmentPoints> selectProductivityPoint() {
		return equipmentPointsDao.selectProductivityPoint();
	}
	@Override
	public int pointImport(String data, EquipmentPoints equipmentPoint) {
		int returnCode = 0;
		ObjectMapper mapper = new ObjectMapper();
		EquipmentPoints equipmentPoints;
		try {
			JsonNode node = mapper.readTree(data);
			for (int i = 0; i < node.size(); i++) {
				String config = "";
				equipmentPoints = new EquipmentPoints();
				equipmentPoints.setName(node.get(i).get("名称").asText());
				equipmentPoints.setXid(node.get(i).get("XID").asText());
				String pointType = node.get(i).get("点类型").asText();
				equipmentPoints.setType(pointType);
				// equipmentPoints.setViewType(new Integer(node.get(i).get("展示类型").asInt()));
				// equipmentPoints.setKind(node.get(i).get("点位性质").asText());
				equipmentPoints.setIndexType(node.get(i).get("指标类型").asText());
				equipmentPoints.setIsCrucial(new Integer(node.get(i).get("是否重要").asInt()));
				equipmentPoints.setComment(node.get(i).get("备注") != null ? node.get(i).get("备注").asText() : "");
				equipmentPoints.setLanguage(node.get(i).get("语言").asText());
				equipmentPoints.setCode(CodeUtil.pointCode(5, equipmentPoints.getType(), equipmentPoints.getKind()));
				if (pointType.equals(CommonUtils.POINT_TYPE_MN)) {
					config = node.get(i).get("单位").asText() + "|$|" + node.get(i).get("最小值").asText() + "|$|"
							+ node.get(i).get("最大值").asText();
				}
				if (pointType.equals(CommonUtils.POINT_TYPE_SZ)) {
					config = node.get(i).get("0代表含义").asText() + "|$|" + node.get(i).get("1代表含义").asText() + "|$|"
							+ (node.get(i).get("0展示颜色") != null ? node.get(i).get("0展示颜色").asText() : "") + "|$|"
							+ (node.get(i).get("1展示颜色") != null ? node.get(i).get("1展示颜色").asText() : "");
				}
				equipmentPoints.setConfig(config);
				equipmentPoints.setIsProductivity(new Integer(1));// 是否为产量点位 1 是 0 否
				equipmentPoints.setRange(new Integer(2));// '监控范围：1-产线，2-设备'
				equipmentPoints.setCustomerCode(equipmentPoint.getCustomerCode());
				equipmentPoints.setEquipmentCode(equipmentPoint.getEquipmentCode());
				equipmentPoints.setStatus(CommonUtils.SUCCESS_NUM);
				returnCode = equipmentPointsDao.insert(equipmentPoints);
				returnCode = equipmentPointsDao.insertInfo(equipmentPoints);
			}
		} catch (IOException e) {
			LOG.error("点位导入异常\t", e);
		}
		return returnCode;
	}
	@Override
	public void pointExport(EquipmentPoints equipmentPoints, HttpServletResponse response) {
		List<EquipmentPoints> data = equipmentPointsDao.selectListByCondition(equipmentPoints);
		PointExport export;
		List<PointExport> result = new ArrayList<PointExport>();
		for (EquipmentPoints point : data) {
			export = new PointExport();
			export.setCode(point.getCode());
			export.setXid(point.getXid());
			export.setName(point.getName());
			export.setType(point.getType());
			export.setViewType(point.getViewType());
			export.setIsCrucial(point.getIsCrucial());
			export.setComment(point.getComment());
			export.setLanguage(point.getLanguage());
			export.setConfig(point.getConfig());
			result.add(export);
		}
		// 设置表头
		String exportData = "[{\"colkey\":\"code\",\"name\":\"点位编码\",\"hide\":false},"
				+ "{\"colkey\":\"xid\",\"name\":\"XID\",\"hide\":false},"
				+ "{\"colkey\":\"name\",\"name\":\"名称\",\"hide\":false},"
				+ "{\"colkey\":\"type\",\"name\":\"点类型\",\"hide\":false},"
				+ "{\"colkey\":\"viewType\",\"name\":\"展示类型\",\"hide\":false},"
				+ "{\"colkey\":\"indexType\",\"name\":\"指标类型\",\"hide\":false},"
				+ "{\"colkey\":\"isCrucial\",\"name\":\"是否重要\",\"hide\":false},"
				+ "{\"colkey\":\"comment\",\"name\":\"备注\",\"hide\":false},"
				+ "{\"colkey\":\"language\",\"name\":\"语言\",\"hide\":false},"
				+ "{\"colkey\":\"unit\",\"name\":\"单位\",\"hide\":false},"
				+ "{\"colkey\":\"min\",\"name\":\"最小值\",\"hide\":false},"
				+ "{\"colkey\":\"max\",\"name\":\"最大值\",\"hide\":false},"
				+ "{\"colkey\":\"meaningZero\",\"name\":\"0代表含义\",\"hide\":false},"
				+ "{\"colkey\":\"meaningOne\",\"name\":\"1代表含义\",\"hide\":false},"
				+ "{\"colkey\":\"colourZero\",\"name\":\"0展示颜色\",\"hide\":false},"
				+ "{\"colkey\":\"colourOne\",\"name\":\"1展示颜色\",\"hide\":false}]";
		ObjectMapper mapper = new ObjectMapper();
		mapper.setSerializationInclusion(Include.NON_NULL);
		List<Map<String, Object>> titles = new ArrayList<Map<String, Object>>();
		try {
			JsonNode node = mapper.readTree(exportData);
			Map<String, Object> title;
			for (int i = 0; i < node.size(); i++) {
				title = new HashMap<String, Object>();
				title.put("colkey", node.get(i).get("colkey").asText());
				title.put("name", node.get(i).get("name").asText());
				titles.add(title);
			}
		} catch (JsonProcessingException e) {
			LOG.error("点位导出异常\t", e);
			titles = null;
		} catch (IOException e) {
			LOG.error("点位导出异常\t", e);
			titles = null;
		}
		POIUtils.exportToExcel(titles, result, equipmentPoints.getEquipmentCode(), response);
	}
	@Override
	public int checkEquipmentsState(String customTag) {
		int returnCode = 0;
		long time = System.currentTimeMillis() / 1000;
		List<EquipmentsAttr> list = equipmentsAttrDao.selectEquListByCustomTag(customTag);
		if (JudgeNullUtil.iList(list)) {
			Map<String, Map<String, Object>> parames = new HashMap<String, Map<String, Object>>();
			Map<String, Object> param = null;
			for (EquipmentsAttr model : list) {
				if (parames.get(model.getEquipmentCode()) == null) {
					param = new HashMap<>();
				} else {
					param = parames.get(model.getEquipmentCode());
				}
				param.put(model.getCustomTag(), model.getValue());
				param.put("categoryCode", model.getCategoryCode());
				parames.put(model.getEquipmentCode(), param);
			}
			List<Equipments> data = new ArrayList<>();
			Equipments equipment;
			for (Map.Entry<String, Map<String, Object>> model : parames.entrySet()) {
				equipment = new Equipments();
				equipment.setCode(model.getKey());
				if (!model.getValue().get("categoryCode").equals("WBCLJCQ")) {
					if (model.getValue().get(BxClientModel.IP) != null
							&& model.getValue().get(BxClientModel.PORT) != null) {
						String ip = (String) model.getValue().get(BxClientModel.IP);
						int port = Integer.parseInt((String) model.getValue().get(BxClientModel.PORT));
						boolean status;
						try {
							status = TcpClientUtil.ping2(ip, port);
							if (status) {// 正常
								equipment.setCurrentState(CommonUtils.EQU_STATE_NORMAL);
							} else {
								equipment.setCurrentState(CommonUtils.EQU_STATE_OFFLINE);
							}
						} catch (UnknownHostException e) {
							equipment.setCurrentState(CommonUtils.EQU_STATE_OFFLINE);
							LOG.debug("method:[checkEquipmentsState] is unknownHostException, error: {}, \r\n data: {}",
									e, model);
						} catch (SocketException e) {
							equipment.setCurrentState(CommonUtils.EQU_STATE_OFFLINE);
							LOG.debug("method:[checkEquipmentsState] is SocketException, error: {}, \r\n data: {}", e,
									model);
						} catch (IOException e) {
							equipment.setCurrentState(CommonUtils.EQU_STATE_OFFLINE);
							LOG.error("method:[checkEquipmentsState] is bad, error: {}, \r\n data: {}", e, model);
						}
					} else {
						equipment.setCurrentState(CommonUtils.EQU_STATE_NO_SET_PARAME);
					}
				} else {// 微波车检仪器
					if (model.getValue().get(BxClientModel.IP) != null) {
						String ip = (String) model.getValue().get(BxClientModel.IP);
						boolean status;
						try {
							status = TcpClientUtil.ping(ip);
							if (status) {// 正常
								equipment.setCurrentState(CommonUtils.EQU_STATE_NORMAL);
							} else {
								equipment.setCurrentState(CommonUtils.EQU_STATE_OFFLINE);
							}
						} catch (UnknownHostException e) {
							equipment.setCurrentState(CommonUtils.EQU_STATE_OFFLINE);
							LOG.debug("method:[checkEquipmentsState] is unknownHostException, error: {}, \r\n data: {}",
									e, model);
						} catch (SocketException e) {
							equipment.setCurrentState(CommonUtils.EQU_STATE_OFFLINE);
							LOG.debug("method:[checkEquipmentsState] is SocketException, error: {}, \r\n data: {}", e,
									model);
						} catch (IOException e) {
							equipment.setCurrentState(CommonUtils.EQU_STATE_OFFLINE);
							LOG.error("method:[checkEquipmentsState] is bad, error: {}, \r\n data: {}", e, model);
						} catch (Exception e) {
							equipment.setCurrentState(CommonUtils.EQU_STATE_OFFLINE);
							LOG.error("method:[checkEquipmentsState] is bad, error: {}, \r\n data: {}", e, model);
						}
					} else {
						equipment.setCurrentState(CommonUtils.EQU_STATE_NO_SET_PARAME);
					}
				}
				data.add(equipment);
			}
			Map<String, Object> map = new HashMap<>();
			map.put("list", data);
			returnCode = equipmentDao.updateBatchCurrentStateByCondition(map);
		}
		LOG.debug("update equipments state is success, useTime: {}, updateCount: {}", System.currentTimeMillis() - time,
				returnCode);
		return returnCode;
	}
	@Override
	public List<EquipmentPoints> selectListByIndexType(EquipmentPoints equipmentsPoints) {
		return equipmentPointsDao.selectListByIndexType(equipmentsPoints);
	}
}
